/*
 * Copyright 2015 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

package core.api.a1;


import api.kiecontainer.Environment;
import api.kiecontainer.FactHandle;
import api.kiecontainer.ReleaseId;
import api.kieservices.Resource;
import core.api.a2.PropagationContext;
import core.api.a4.FactHandleFactory;
import core.impl.p1.EntryPointNode;
import core.impl.p1.LeftTupleSource;
import core.impl.p1.Rete;
import core.impl.p1.RuleBaseConfiguration;
import core.impl.p1.RuleBasePartitionId;
import core.impl.p1.RuleUnitRegistry;
import core.impl.p1.StatefulKnowledgeSessionImpl;
import core.impl.p1.TraitRegistry;
import core.impl.p1.TypeDeclaration;
import core.impl.p2.RuleImpl;
import core.impl.p2.SegmentMemory;
import core.impl.p2.SessionConfiguration;
import core.impl.p3.ClassFieldAccessorCache;
import core.impl.p3.ReteooBuilder;
import core.impl.p5.InvalidPatternException;
import core.impl.p5.TripleStore;
import internal.api.a1.KnowledgeBase;
import api.kiecontainer.Process;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

public interface InternalKnowledgeBase extends KnowledgeBase {

    String getId();

    RuleBasePartitionId createNewPartitionId();

    RuleBaseConfiguration getConfiguration();

    void readLock();
    void readUnlock();

    void lock();
    void unlock();

    void enqueueModification(Runnable modification);
    boolean flushModifications();

    int nextWorkingMemoryCounter();

    int getWorkingMemoryCounter();

    FactHandleFactory newFactHandleFactory();

    FactHandleFactory newFactHandleFactory(int id, long counter) throws IOException;

    Map<String, Class<?>> getGlobals();

    int getNodeCount();
    int getMemoryCount(String unitName);

    void executeQueuedActions();

    ReteooBuilder getReteooBuilder();

    void registerAddedEntryNodeCache(EntryPointNode node);
    Set<EntryPointNode> getAddedEntryNodeCache();

    void registeRremovedEntryNodeCache(EntryPointNode node);
    Set<EntryPointNode> getRemovedEntryNodeCache();

    Rete getRete();

    ClassLoader getRootClassLoader();

    void assertObject(FactHandle handle,
                      Object object,
                      PropagationContext context,
                      InternalWorkingMemory workingMemory);

    void retractObject(FactHandle handle,
                       PropagationContext context,
                       StatefulKnowledgeSessionImpl workingMemory);

    void disposeStatefulSession(StatefulKnowledgeSessionImpl statefulSession);

    StatefulKnowledgeSessionImpl getCachedSession(SessionConfiguration config, Environment environment);

    TripleStore getTripleStore();

    TraitRegistry getTraitRegistry();

    Class<?> registerAndLoadTypeDefinition(String className, byte[] def) throws ClassNotFoundException;

    InternalKnowledgePackage getPackage(String name);
    void addPackages(InternalKnowledgePackage[] pkgs);
    void addPackage(InternalKnowledgePackage pkg);
    void addPackages(final Collection<InternalKnowledgePackage> newPkgs);
    Map<String, InternalKnowledgePackage> getPackagesMap();

    ClassFieldAccessorCache getClassFieldAccessorCache();

    InternalWorkingMemory[] getWorkingMemories();

    boolean hasSegmentPrototypes();
    void invalidateSegmentPrototype(LeftTupleNode rootNode);
    SegmentMemory createSegmentFromPrototype(InternalWorkingMemory wm, LeftTupleSource tupleSource);
    SegmentMemory.Prototype getSegmentPrototype(SegmentMemory segment);

    void addRule(InternalKnowledgePackage pkg, RuleImpl rule) throws InvalidPatternException;
    void removeRule(InternalKnowledgePackage pkg, RuleImpl rule) throws InvalidPatternException;
    void removeRules(InternalKnowledgePackage pkg, List<RuleImpl> rules) throws InvalidPatternException;

    void addProcess(Process process);
    void removeProcess(final String id);

    void addGlobal(String identifier, Class clazz);
    void removeGlobal(String identifier);

    boolean removeObjectsGeneratedFromResource(Resource resource);

    TypeDeclaration getTypeDeclaration(Class<?> clazz);
    TypeDeclaration getExactTypeDeclaration(Class<?> clazz);
    TypeDeclaration getOrCreateExactTypeDeclaration(Class<?> clazz);
    Collection<TypeDeclaration> getTypeDeclarations();
    void registerTypeDeclaration(TypeDeclaration newDecl, InternalKnowledgePackage newPkg);

	ReleaseId getResolvedReleaseId();
	void setResolvedReleaseId(ReleaseId currentReleaseId);
	String getContainerId();
	void setContainerId(String containerId);
	void initMBeans();

    RuleUnitRegistry getRuleUnitRegistry();
    boolean hasUnits();
}
